home *** CD-ROM | disk | FTP | other *** search
- ##############################################################################
- ##############################################################################
- # Commands.tcl
- ##############################################################################
- ##############################################################################
- # Here you will implemented a few helpful procedures that don't quite fit
- # anywhere else.
- ##############################################################################
- ##############################################################################
- # Copyright 2000-2001 AndrΘs Garcφa Garcφa -- fandom@retemail.es
- # Distributed under the terms of the GPL v2
- ##############################################################################
- ##############################################################################
-
- namespace eval Commands {
-
- set sedIndex 0
-
- ##############################################################################
- # PlaceWindow
- # Places a given window in the screen, it makes sure the window won't go
- # out of the screen, unless it is way too big of course.
- #
- # Parameters:
- # win: Path of the window.
- # x,y: The coordinates where we want the top-left corner to be placed,
- # unless that wouldn't allow the the whole window to be seen.
- # width,height: Width and height of the window.
- ##############################################################################
- proc PlaceWindow {win x y width height} {
-
- set screenWidth [winfo screenwidth $win]
- set screenHeight [winfo screenheight $win]
-
- if {[expr $x + $width + 15]>$screenWidth} {
- set x [expr {$screenWidth - $width - 15}]
- }
- if {[expr $y + $height + 30]>$screenHeight} {
-
- set y [expr {$screenHeight - $height - 30}]
- }
- if {$x<0} {
- set x 0
- }
- if {$y<0} {
- set y 0
- }
- wm geometry $win ${width}x$height+$x+$y
- return
- }
-
- ##############################################################################
- # Touch
- # This procedure will create an empty file
- #
- # Parameters:
- # fileName: The file to create.
- ##############################################################################
- proc Touch {fileName} {
-
- if {![file exists "$fileName"]} {
- set handle [open "$fileName" w]
- close $handle
- }
- return
- }
-
- ##############################################################################
- # SedReadFile
- # Reads a given file into memory for the pseudosed command to work on.
- #
- # Parameters:
- # fileName: The file to read.
- #
- # Returns:
- # - '0' if all went well.
- # - '1' if not.
- ##############################################################################
- proc SedReadFile {fileName} {
- variable workFile
- variable workFileLines
-
- catch {unset workFile}
- if {[catch {open "$fileName" r} handle]} {
- return 1
- }
- set workFileLines ""
- for {set i 0} {![eof $handle]} {incr i} {
- set workFile($i) [gets $handle]
- if {[regexp {=} $workFile($i)]} {
- lappend workFileLines $i
- }
- }
- close $handle
-
- return 0
- }
-
- ##############################################################################
- # SedWriteFile
- # Saves whatever is in the workFile array into the given file. The file
- # must not already exist.
- #
- # Parameter:
- # fileName: file to use to save the data.
- #
- # Returns:
- # - '0' if all went well.
- # - '1' if not.
- ##############################################################################
- proc SedWriteFile {fileName} {
- variable workFile
-
- if {[catch {open "$fileName" w} handle]} {
- return 1
- }
- for {set i 0} {![catch "set workFile($i)"]} {incr i} {
- puts $handle "$workFile($i)"
- }
- close $handle
-
- return 0
- }
-
- ##############################################################################
- # DeRexString
- # Prepares a string so that it is safe to use it in a regular expresion,
- # for example, all '+' are changed to '\+'.
- #
- # Parameters:
- # - old: The string to make safe.
- #
- # Returns:
- # The string now safe.
- ##############################################################################
- proc DeRexString {old} {
-
- set old [string map {../ \\.\\./ ./ \\./ * \\* + \\+ ? \\? ) \\) \
- ( \\( ] \\] [ \\[ $ \\$} $old]
-
- return $old
- }
-
- ##############################################################################
- # SedChangeEnter
- # Enters a new change in to the 'sedChanges' array.
- #
- # Parameters:
- # - old: The regular expresion to subtitute.
- # - new: The substitute.
- ##############################################################################
- proc SedChangeEnter {old new} {
- variable sedChanges
- variable sedIndex
-
- if {$old==$new} {
- return
- }
-
- if {$new==""} {
- set sedChanges($sedIndex,old) $old
- set sedChanges($sedIndex,new) $new
-
- incr sedIndex
-
- set sedChanges($sedIndex,old) ""
- set sedChanges($sedIndex,new) ""
-
- incr sedIndex
-
- return
- }
-
- set old [DeRexString $old]
- regsub -all {&} $new {\\&} new
-
- set oldLink "(href|src)(\\s*)(=)(\\s*)(\'|\")($old)(\"|\')"
- set newLink "\\1=\"$new\""
-
- set sedChanges($sedIndex,old) $oldLink
- set sedChanges($sedIndex,new) $newLink
-
- set oldLink "(href|src)(\\s*)(=)(\\s*)($old)(\ |>)"
- set newLink "\\1=\"$new\"\\6"
-
- incr sedIndex
-
- set sedChanges($sedIndex,old) $oldLink
- set sedChanges($sedIndex,new) $newLink
-
- incr sedIndex
-
- return
- }
-
- ##############################################################################
- # SedChange
- # Goes through the file in 'workFile' chaging one link.
- #
- # Parameter:
- # index: The index of the link to change in the sedChanges variable.
- #
- # Returns:
- # - '0' if there was no change.
- # - '1' if a change was found.
- ##############################################################################
- proc SedChange {index} {
- variable workFile
- variable sedChanges
- variable startLine
- variable workFileLines
-
- set old $sedChanges($index,old)
- set new $sedChanges($index,new)
- for {set i $startLine} {1} {incr i} {
- set line [lindex $workFileLines $i]
- if {$line==""} {
- break
- }
- if {[regsub -nocase "$old" $workFile($line) "$new" workFile($line)]} {
- set startLine $i
- return 1
- }
- }
- return 0
- }
-
- ############################################################################
- # Sed
- # Goes through a given file and makes the requested changes to it.
- #
- # Parameter:
- # fileName: file to change.
- #
- # Returns:
- # - '0' if all went well.
- # - '1' if not.
- ##############################################################################
- proc Sed {fileName} {
- variable workFile
- variable sedChanges
- variable sedIndex
- variable startLine
-
- if {[file exists $fileName.html]} {
- set fileName $fileName.html
- }
- if {[SedReadFile $fileName]==1} {return 1}
-
- for {set i 0 ; set startLine 0} {![catch "set sedChanges($i,old)"]} {incr i} {
- if {([SedChange $i]==1)&&([expr {$i%2}]==0)} {
- incr i
- }
- }
-
- catch {unset sedChanges}
- set sedIndex 0
-
- if {[SedWriteFile $fileName]==1} {return 1}
-
- return 0
- }
-
- ###############################################################################
- # ChangePage
- # Changes a html page, so that there is consistency with the local
- # directories. After this procedure is run through a page all it's links
- # should be between double qoutes ("), the ones that have been downloaded
- # will be relative to the the current directory and the ones that where
- # not downloaded will have the complete url.
- #
- # Parameters
- # url: The url of the page about to be changed.
- ###############################################################################
- proc ChangePage {url} {
- global siteUrl
- global directories
-
- if {$HtmlParser::baseTag!=""} {
- Commands::SedChangeEnter <$HtmlParser::baseTag> ""
- }
-
- for {set i 1} {$i<$HtmlParser::nLinks} {incr i} {
- set link $HtmlParser::links($i,file)
- # Even if we now filter the file out, it may already be there
- # due to a former download.
- set file [UrlToFile $HtmlParser::links($i,url) $directories(base)]
- if {($HtmlParser::links($i,ok)==1)||([file exists $file])} {
- set tag ""
- regexp {(#)(.*)} $HtmlParser::links($i,url) tag
- set newLink [RelativePath $url $HtmlParser::links($i,url)]
- Commands::SedChangeEnter $link $newLink$tag
- } else {
- set newLink $HtmlParser::links($i,url)
- if {$link!=$newLink} {
- Commands::SedChangeEnter $link $newLink
- }
- }
- }
-
- set fileName [UrlToFile $url $directories(base)]
- if {[file exists $fileName.orig]} {
- file copy -force $fileName.orig $fileName
- } elseif {[file exists $fileName.html.orig]} {
- file copy -force $fileName.html.orig $fileName.html
- } elseif {[file exists $fileName.html]} {
- file copy $fileName.html $fileName.html.orig
- } else {
- file copy $fileName $fileName.orig
- }
-
- Commands::Sed $fileName
-
- return
- }
-
- ###############################################################################
- # UrlToFile
- # Given an Url this procedure will return the file in which it will be
- # saved.
- #
- # Extra care since Windows doesn't like certain names for directories.
- #
- # Parameters
- # url: The url to process.
- # baseDir: The local directory into which the site is saved.
- #
- # Returns:
- # The file in which it will be saved complete with full path.
- ###############################################################################
- proc UrlToFile {url {baseDir ""}} {
- global getleftState
-
- set parsedUrl [HtmlParser::ParseUrl $url]
- set prot [lindex $parsedUrl 0]
- set domain [string tolower [lindex $parsedUrl 1]]
- set dir [lindex $parsedUrl 2]
- set file [lindex $parsedUrl 3]
-
- if {$file==""} {
- if {$prot=="ftp"} {
- set file index.txt
- } else {
- set file index.html
- }
- }
-
- set fileName ${domain}$dir/$file
- set fileName [TidyNames $fileName]
- while {[regexp {(?:%)([0-9ABCDEFabcdef][0-9ABCDEFabcdef])} $fileName nada tmp]} {
- if {$tmp=="26"} {
- set newTmp \\&
- } else {
- set newTmp [format "%c" "0x$tmp"]
- }
- regsub -all "%$tmp" $fileName "$newTmp" fileName
- }
-
- if {$baseDir==""} {
- set baseDir $::directories(base)
- }
-
- set fileName [file join $baseDir $fileName]
-
- if {$getleftState(os)=="win"} {
- regsub -nocase {(/)(com[1-9]|aux|nul|con|lpt[1-9])(/|\.|$)} $fileName \
- {/g\2\3} fileName
- }
-
- return $fileName
- }
-
- ###############################################################################
- # TidyNames
- # Removes from the name and path of files things like '?' '~' '+' '-'
- #
- # Returns
- # The filename without those characters.
- ###############################################################################
- proc TidyNamesOld {nombre} {
-
- regsub -all {~} $nombre {} nombre
- regsub -all {\*} $nombre {} nombre
- if {[regexp {(?:^.:)(.*)} $nombre nada filename]} {
- regsub -all {:} $filename {} filename
- set nombre $filename
- } else {
- regsub -all {:} $nombre {} nombre
- }
- if {[regexp {([^\?]+)(?:\?)(.*)} $nombre nada uno dos]} {
- regsub -all {\?} $dos {} dos
- regsub -all {\+} $dos {} dos
- regsub -all {/} $dos {} dos
- regsub -all {\\} $dos {} dos
- set nombre $uno$dos
- }
- return $nombre
- }
-
- proc TidyNames {nombre} {
- set nombre [string map {~ "" * ""} $nombre]
- regsub {(^.:)(.*)} $nombre {} nombre
- set nombre [string map {: ""} $nombre]
-
- if {[regexp {([^\?]+)(?:\?)(.*)} $nombre nada uno dos]} {
- set dos [string map {? "" + "" / "" \\ ""} $dos]
- set nombre $uno$dos
- }
- return $nombre
- }
-
- ###############################################################################
- # RelativePath
- # The function returns the relative path from the referer page to the linked
- # page.
- #
- # Parameter:
- # urlRef. The referer page.
- # urlNew: The url whose link we are calculating.
- #
- # Returns:
- # The link for the changed page.
- ###############################################################################
- proc RelativePath {urlRef urlNew} {
- global directories siteUrl
-
- set fileRef [UrlToFile $urlRef $directories(base)]
- set fileNew [UrlToFile $urlNew $directories(base)]
-
- regexp -nocase "(?:^$directories(base)/)(.*)" $fileRef nada fileRef
- regexp -nocase "(?:^$directories(base)/)(.*)" $fileNew nada fileNew
-
- set listDirRef [split [file dirname $fileRef] /]
- foreach dir $listDirRef {
- regsub -all {\+} $dir {\\+} dir
- if {[regexp "(?:^$dir/)(.*)" $fileNew nada fileNew]} {
- regexp "(?:^$dir/)(.*)" $fileRef nada fileRef
- } else {
- break
- }
- }
- set jumps [regsub -all {/} $fileRef {} nada]
- for {set i 0} {$i<$jumps} {incr i} {
- set fileNew ../$fileNew
- }
-
- return $fileNew
- }
-
- }
-